package com.tx.admin.core.exception;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import com.tx.admin.core.vo.EntityVo;
import com.tx.admin.core.vo.SuperVo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.tx.admin.modules.base.entity.ExceptionEntity;
import com.tx.admin.modules.base.service.ExceptionService;

@ControllerAdvice  
public class ExceptionHeader {

	@Autowired
	private ExceptionService exceptionService;
    
    @ExceptionHandler(value = {UnknownAccountException  .class}) 
   @ResponseBody
    public SuperVo UnknownAccountException  (final UnknownAccountException   ex, final HttpServletRequest req, final HttpServletResponse resp) {
       	this.save(ex);
    	resp.setStatus(601);

    	SuperVo vo =new SuperVo();
    	vo.setMsg(ex.getMessage());
    	return vo;
    }

    
    @ExceptionHandler(value = {UnauthenticatedException.class}) 
    @ResponseBody
    public SuperVo UnauthenticatedException(final UnauthenticatedException ex, final HttpServletRequest req,final HttpServletResponse resp) {  
       	this.save(ex);
    	resp.setStatus(600);
    	SuperVo vo =new SuperVo();
    	vo.setMsg("请登陆！");
    	return vo;
    }
    
    @ExceptionHandler(value = {MethodArgumentNotValidException.class}) 
    @ResponseBody
    public SuperVo Exception(final MethodArgumentNotValidException ex, final HttpServletRequest req,final HttpServletResponse resp) {  
       	this.save(ex);
    	resp.setStatus(600);
    	HashMap<String,Object> map =new HashMap<>();

    	ex.getBindingResult().getFieldErrors().forEach(val -> {
    		map.put(val.getField(),val.getDefaultMessage());
    	});

    	EntityVo vo =new EntityVo<>();
    	vo.setMsg("注解参数校验异常");
    	vo.setEntity(map);
    	return vo;
    }
    
    @ExceptionHandler(value = {ConstraintViolationException.class}) 
    @ResponseBody
    public SuperVo Exception(final ConstraintViolationException ex, final HttpServletRequest req,final HttpServletResponse resp) {  
       	this.save(ex);
    	resp.setStatus(600);
    	HashMap<String,Object> map =new HashMap<>();

    	
    	for(ConstraintViolation cv : ex.getConstraintViolations()) {
    		map.put(cv.getPropertyPath().toString(),cv.getMessage());
        	
    	}

    	EntityVo vo =new EntityVo<>();
    	vo.setMsg("sql参数校验异常");
    	vo.setEntity(map);
    	return vo;
    }

    @ExceptionHandler(value = {Exception.class}) 
    @ResponseBody
    public SuperVo Exception(final Exception ex, final HttpServletRequest req,final HttpServletResponse resp) {  
    	this.save(ex);
    	resp.setStatus(600);
    	SuperVo vo =new SuperVo();
    	vo.setMsg(ex.getMessage());
    	return vo;
    }
    
    
    private void save(Exception ex) {
    	ex.printStackTrace();
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            PrintStream pout = new PrintStream(out);
            ex.printStackTrace(pout);
        	String content = new String(out.toByteArray());
            pout.close();
            out.close();
        	ExceptionEntity ee = new ExceptionEntity();
        	ee.setTitle(ex.getMessage());
        	ee.setContent(content);
        	exceptionService.save(ee);
        } catch (Exception e) {
        }

    }
    
    
}
